<?php

namespace app\admin\service;

use app\admin\dao\PromotionGroupDao;
use app\admin\dao\PromotionGroupFeedbackDao;
use app\admin\model\UM as UM;
use app\common\model\PromotionAction;
use app\common\model\PromotionEvent;
use app\common\model\PromotionGroup;
use app\common\model\PromotionGroupFeedback;
use ShidianUtil\Exception\DataNotExistException;

/**
 * Class PromotionGroupCallbackService
 * @package app\admin\service
 */
class PromotionGroupCallbackService
{
    // dao
    private PromotionGroupDao $promotionGroupDao;
    private PromotionGroupFeedbackDao $feedbackDao;

    public function __construct(PromotionGroupDao $promotionGroupDao, PromotionGroupFeedbackDao $feedbackDao)
    {
        $this->promotionGroupDao = $promotionGroupDao;
        $this->feedbackDao = $feedbackDao;
    }

    /**
     * 查询
     * @param UM|null $user
     * @param int $id
     * @return PromotionGroup
     */
    public function read(?UM $user, int $id): ?PromotionGroup
    {
        //这里如果要修改查询，建议把查询放到dao层去
        $record = $this->promotionGroupDao->find($id);

        $record->setRelation('events', $this->readEvents($record->id));

        return $record;
    }

    /**
     * 更新
     * @param UM $user
     * @param int $id
     * @param array $params
     * @return PromotionGroup
     */
    public function modify(UM $user, int $id, array $params): PromotionGroup
    {
        //这里如果要修改查询，建议把查询就放到这里
        $record = PromotionGroup::field(true)->where('id', $id)->find();

        if (is_null($record)) {
            throw new DataNotExistException('该对象不存在或已被删除');
        }

        $allowField = [];
        $this->promotionGroupDao->updateActive($record, $params, $allowField);

        $this->saveEvents($record->id, $params['events'] ?? []);

        return $record;
    }

    private function readEvents($promotionGroupId)
    {
        // 查询配置 ls_promotion_group_feedback
        $feedbacks = PromotionGroupFeedback::where('promotionGroupId', $promotionGroupId)
                                           ->select()
                                           ->column(null, 'promotionEventId');

        // 查询事件 ls_promotion_event
        $events = PromotionEvent::order('id', 'ASC')
                                ->hidden(['updated', 'created'])
                                ->select();

        // 查询行为 ls_promotion_action
        $actions = PromotionAction::order('ord', 'ASC')
                                  ->order('id', 'ASC')
                                  ->hidden(['updated', 'created', 'ord'])
                                  ->select();

        // 组合
        $events->each(function (PromotionEvent $event) use ($promotionGroupId, $feedbacks, $actions) {

            $feedback = $feedbacks[$event->id] ?? null;

            // 事件
            $event->isSel = $feedback ? $feedback->isSel : 102;
            $event->deductionBase = $feedback ? $feedback->deductionBase : 0;
            $event->deductionProportion = $feedback ? $feedback->deductionProportion : 0;
            $event->promotionGroupId = $promotionGroupId;

            // 行为
            $actionIds = $feedback ? $feedback->actionIds : [];
            $actions = clone_collection($actions);
            $actions->each(function (PromotionAction $action) use ($actionIds) {
                $action->isSel = in_array($action->id, $actionIds) ? 101 : 102;
                // dump($action->isSel);
            });

            $event->setRelation('actions', $actions);
        });

        return $events;
    }

    private function saveEvents($promotionGroupId, array $events): void
    {
        // 清空旧数据
        PromotionGroupFeedback::destroy(function ($query) use ($promotionGroupId) {
            $query->where('promotionGroupId', $promotionGroupId);
        }, true);

        foreach ($events as $event) {
            $actionIds = [];
            foreach ($event['actions'] as $action) {
                if ($action['isSel'] == 101) {
                    $actionIds[] = $action['id'];
                }
            }
            $data = [
                'promotionGroupId' => $promotionGroupId,
                'promotionEventId' => $event['id'],
                'isSel' => $event['isSel'] ?? 102,
                'actionIds' => $actionIds,
                'deductionBase' => $event['deductionBase'],
                'deductionProportion' => $event['deductionProportion'],
            ];
            $this->feedbackDao->replaceActive($data);
        }
    }
}
